package com.example.study.jetpack.compose

import android.util.Log
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.gestures.rememberTransformableState
import androidx.compose.foundation.gestures.transformable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kotlin.math.roundToInt

/**
 *  created by ws
 *   on 2022/3/1
 *   describe:https://blog.csdn.net/Mr_Tony/article/details/118771707?spm=1001.2014.3001.5502
 */
class Compose的手势 {
    /*Compose中的手势会比xml的方式要使用更广泛*/
    /*clickable
    * 在compose中对手势封装了一些单击,双击,长按事件
    * 不过点击事件用的多一些
    * 示例:*/
    @Composable
    fun ClickableSample() {
        val count = remember { mutableStateOf(0) }
        // content that you want to make clickable
        Text(
            text = count.value.toString(),
            modifier = Modifier.clickable { count.value += 1 }
        )
    }
    /*detectTapGestures
    * 如果需要对基本的手势进行监测,则可以使用PointerInputScope.detectTapGestures
    * 或PointerInputScope.detectDragGestures
    * PointerInputScope.detectTapGestures示例
    * */
    @Composable
    private fun scrollBoxes() {
        Column(
            modifier = Modifier
                .background(Color.LightGray)
                .size(100.dp)
                .verticalScroll(rememberScrollState())
                .pointerInput(Unit){
                    detectTapGestures(
                        onPress = { /* Called when the gesture starts */ },
                        onDoubleTap = { /* Called on Double Tap */ },
                        onLongPress = { /* Called on Long Press */ },
                        onTap = { /* Called on Tap */ }
                    )
                }
        ) {
            repeat(10) {
                Text("Item $it", modifier = Modifier.padding(2.dp))
            }
        }
    }
/*PointerInputScope.detectDragGestures手势拖动教程卡伊参考以下链接;
* https://developer.android.google.cn/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.input.pointer.PointerInputScope).detectDragGestures(kotlin.Function1,kotlin.Function0,kotlin.Function0,kotlin.Function2)
*/

/*Dragging
* dragging可以检测手势单一方向拖动但是并不会移动元素.度过想要移动的话可以通过offset
* 来进行移动,示例:
* var offsetX by remember { mutableStateOf(0f) }
Text(
    modifier = Modifier
        .offset { IntOffset(offsetX.roundToInt(), 0) }
        .draggable(
            orientation = Orientation.Horizontal,
            state = rememberDraggableState { delta ->
                offsetX += delta
            }
        ),
    text = "Drag me!"
)
如果想要控制整个手势拖动,可以pointerInput来进行监测,示例:
* Box(modifier = Modifier.fillMaxSize()) {
    var offsetX by remember { mutableStateOf(0f) }
    var offsetY by remember { mutableStateOf(0f) }

    Box(
        Modifier
            .offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) }
            .background(Color.Blue)
            .size(50.dp)
            .pointerInput(Unit) {
                detectDragGestures { change, dragAmount ->
                    change.consumeAllChanges()
                    offsetX += dragAmount.x
                    offsetY += dragAmount.y
                }
            }
    )
}
*/

    /*Swiping
    * 有时候会有滑动切换或者滑动关闭等类似需求,可以使用swipeable修饰符实现.
    * 该swipeable修改器允许你将他发布的时候,通常对两个或连个以上的锚点动画中
    * 的方向定义的额元素.对此的常见的用法是实现"滑动到关闭模式"
    * 需要注意的是,这个修饰符不会移动元素,它只检测手势.你需要保持状态并在屏幕上表示它,
    * 例如,通过offset修改器移动元素
    * swipeable修改器中需要可滑动状态,可以使用来创建和记住rememberSwipeableState().
    * 这种状态下还提供了(见以编程动画的一组有用的方法来描点snapTo,animateTo,performFling和
    * performDrag),以及属性来观察拖动进展
    * 滑动手势可以配置位具有不同阈值类型,例如fixedThreshold(DP)和Fractionalthreshould(Float),
    * 并且对于每个锚点从到组合,它们可以不同
    * 为了获得更大的灵活性,你可以配置resistance何时滑动越过边界,并且velocityThreshould
    * 即使threshoulds尚未到达位置,也可以将滑动动画设置为下一个状态
    * */
    @ExperimentalMaterialApi
    @Composable
    private fun swipeableSample() {
        val width = 96.dp
        val squareSize = 48.dp

        val swipeableState = rememberSwipeableState(0)
        val sizePx = with(LocalDensity.current) { squareSize.toPx() }
        Log.e("YM","sizePx--$sizePx")
        val anchors = mapOf(0f to 0, sizePx to 1) // Maps anchor points (in px) to states

        Box(
            modifier = Modifier
                .width(width)
                .swipeable(
                    state = swipeableState,
                    anchors = anchors,//主要是存储一些滑动状态,可以在其它地方使用
                    thresholds = { _, _ -> FractionalThreshold(0.3f) },//该值表示远离多少时候回弹到原先位置
                    orientation = Orientation.Horizontal //水平
                )
                .background(Color.LightGray)
        ) {
            Box(
                Modifier
                    .offset { IntOffset(swipeableState.offset.value.roundToInt(), 0) }
                    .size(squareSize)
                    .background(Color.DarkGray)
            )
        }
    }
    /*第二个swipeable,用来加深anchors的理解*/
    @ExperimentalMaterialApi
    @Composable
    private fun swipeableSample2() {
        // Draw a slider-like composable consisting of a red square moving along a
// black background, with three states: "A" (min), "B" (middle), and "C" (max).
        val width = 350.dp
        val squareSize = 50.dp

        val swipeableState = rememberSwipeableState("A")
        val sizePx = with(LocalDensity.current) { (width - squareSize).toPx() }
        val anchors = mapOf(0f to "A", sizePx / 2 to "B", sizePx to "C")

        Box(
            modifier = Modifier
                .width(width)
                .swipeable(
                    state = swipeableState,
                    anchors = anchors,
                    thresholds = { _, _ -> FractionalThreshold(0.5f) },
                    orientation = Orientation.Horizontal
                )
                .background(Color.Black)
        ) {
            Box(
                Modifier
                    .offset { IntOffset(swipeableState.offset.value.roundToInt(), 0) }
                    .size(squareSize)
                    .background(Color.Red),
                contentAlignment = Alignment.Center
            ) {
                Text(swipeableState.currentValue, color = Color.White, fontSize = 24.sp)
            }
        }
    }
/*多点触控:平移,缩放,旋转*/
@Composable
fun TransformableSample() {
    // set up all transformation states
    var scale by remember { mutableStateOf(1f) }
    var rotation by remember { mutableStateOf(0f) }
    var offset by remember { mutableStateOf(Offset.Zero) }
    val state = rememberTransformableState { zoomChange, offsetChange, rotationChange ->
        scale *=zoomChange
        rotation += rotationChange
        offset += offsetChange
    }
    Box(
        Modifier
            // apply other transformations like rotation and zoom
            // on the pizza slice emoji
            .graphicsLayer(
                scaleX = scale,
                scaleY = scale,
                rotationZ = rotation,
                translationX = offset.x,
                translationY = offset.y
            )
            // add transformable to listen to multitouch transformation events
            // after offset
            .transformable(state = state)
            .background(Color.Blue)
            .fillMaxSize()
    )
}
    /*如果需要将缩放，平移和旋转与其他手势结合使用，则可以使用
    * PointerInputScope.detectTransformGestures检测器*/

//    事件分发
//    https://compose.net.cn/design/gesture/custom_gesture/


}